<template>
    <el-tabs
        type="card"
        class="demo-tabs"
        v-model="activeName"
        @tab-change="handleTabChange"
    >
        <el-tab-pane v-for="ele in searchItem.tabs" :label="ele.label" :name="ele.value" :key="ele.label" lazy>
            <div style="margin-bottom: 10px; margin-left: 20px; font-family: 'Helvetica Neue';  font-weight: 500;">
                {{ ele.label }}:
            </div>
            <el-select-v2
                ref="selectMultiTabRef"
                class="bar"
                v-model="modelValue[ele.value]"
                filterable
                placeholder="Select"
                clearable
                highlight-current-row
                :options="filteredOptionsMethod(options[activeName]).value"
                @change="props.updateOptions($refs)"
                :filter-method="filterMethod"
                multiple
                >
                <template #default="{ item }">
                    <div class="flex items-center">
                        <el-tooltip class="item" effect="dark" :content="item.label" placement="top">
                            <span>{{ item.label }}</span>
                        </el-tooltip>
                    </div>
                </template>
            </el-select-v2>
        </el-tab-pane>
    </el-tabs>
</template>

<script lang="ts" setup name="TabMultiSelect">
    import { computed, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue';

    let selectTabMultiRef:any = ref()
    let options:any = ref({})
    let initAllOptions: any = ref({})
    const itemValue:any = ref('') // 选项名
    let activeName = ref('')
    let prevActiveName = ''
    const emit = defineEmits();

    const props = defineProps(['modelValue', 'searchItem', 'filterMethod', 'updateOptions', 'activeName', 'updateTable', 'filteredOptions'])

    function handleTabChange(event:any) {
        updateValues(event)
        props.updateOptions()
    }

    async function updateValues(event:any) {
        nextTick(() => {
            let newSelectedValues = { ...props.modelValue }
            if (prevActiveName) {
                delete newSelectedValues[prevActiveName];
            }
            for (let ele in newSelectedValues) {
                newSelectedValues[ele] = ''
            }
            newSelectedValues[event] = ''
            let searchItem = { ...props.searchItem }
            for (let ele of searchItem.tabs) {
                ele.isChosen = ele.value === event ? true : false
            }
            emit('updateValues', newSelectedValues, searchItem)
        })
    }

    const filterMethod = (query:any) => {
        if (query) {
            const escapeStringRegexp = (string = '') => string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
            const regexp = new RegExp(escapeStringRegexp(query), 'i')

            let filteredOptions = initAllOptions.value[activeName.value].filter((opt: any) => {
                return query ? regexp.test(opt.label || '') : true
            }).sort((a: any, b: any) => {
                const aStartsWith = a.label.toLowerCase().startsWith(query.toLowerCase());
                const bStartsWith = b.label.toLowerCase().startsWith(query.toLowerCase());
                return (aStartsWith === bStartsWith) ? (a.label.length < b.label.length ? -1 : 1) : (aStartsWith ? -1 : 1);
            })
            options.value[activeName.value] = filteredOptionsMethod(filteredOptions).value
        } else {
            options.value[activeName.value] = filteredOptionsMethod(initAllOptions.value[activeName.value]).value
        }
    };

    const filteredOptionsMethod = (opts: any) => {
        // 直接返回的是Object类型的数据，用的时候加上.value
        if (opts) {
            return computed(() => {
                const options = Array.isArray(opts) ? opts : [];
                return options.filter((option: any) => !props.modelValue[props.searchItem.value]?.includes(option.value));
            });
        } else {
            return computed(() => {
                return []
            })
        }
    };

    defineExpose({selectTabMultiRef})


    watch(props.searchItem, (newValue:any) => {
        // initAllOptions.value = props.filteredOptions(newValue).value
        // 理论上应该只在最一开始赋值的时候执行2次,因为有2个tab
        for (let tab of newValue.tabs) {
            initAllOptions.value[tab.value] = props.filteredOptions(tab).value
            options.value[tab.value] = props.filteredOptions(tab).value
        }
    }, {deep: true})

    watch(activeName, (newValue: any, oldValue:any) => {
        prevActiveName = oldValue
    }, {deep: true})

    onBeforeMount(() => {
        itemValue.value = props.searchItem.value
        activeName.value = props.activeName
    })
</script>

<style scoped>
    .bar {
        margin-left: 20px;
        width: 80%;
    }
</style>